package edu.wfu.preparedDishes.order.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.gson.JsonObject;
import edu.wfu.preparedDishes.commodity.entity.CartEntity;
import edu.wfu.preparedDishes.commodity.entity.CommoditySkuEntity;
import edu.wfu.preparedDishes.commodity.entity.CommoditySpuEntity;
import edu.wfu.preparedDishes.commodity.entity.MerchantEntity;
import edu.wfu.preparedDishes.commodity.service.CartService;
import edu.wfu.preparedDishes.commodity.service.MerchantService;
import edu.wfu.preparedDishes.commodity.service.impl.CommoditySkuServiceImpl;
import edu.wfu.preparedDishes.commodity.service.impl.CommoditySpuServiceImpl;
import edu.wfu.preparedDishes.common.utils.PageUtils;
import edu.wfu.preparedDishes.common.utils.Query;
import edu.wfu.preparedDishes.order.WebSoket.WebSocketServer;
import edu.wfu.preparedDishes.order.dao.MerchantOrderDao;
import edu.wfu.preparedDishes.order.dao.OrderDao;
import edu.wfu.preparedDishes.order.entity.dto.CreateAddressDto;
import edu.wfu.preparedDishes.order.entity.dto.CreateOderDto;
import edu.wfu.preparedDishes.order.entity.po.MerchantOrderEntity;
import edu.wfu.preparedDishes.order.entity.po.OrderEntity;
import edu.wfu.preparedDishes.order.entity.vo.*;
import edu.wfu.preparedDishes.order.service.MerchantOrderService;
import edu.wfu.preparedDishes.order.service.OrderService;
import edu.wfu.preparedDishes.user.utils.SnowFlakeUtil;
import org.json.JSONArray;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;


@Service("orderService")
public class OrderServiceImpl extends ServiceImpl<OrderDao, OrderEntity> implements OrderService {

    @Resource
    OrderDao orderDao;

    @Autowired
    private MerchantService merchantService;

    @Autowired
    private CommoditySpuServiceImpl comspuService;

    @Autowired
    private CommoditySkuServiceImpl skuService;

    @Autowired
    private CartService cartService;
    @Autowired
    private MerchantOrderService merchantOrderService;
    @Autowired
    private OrderService orderService;

    @Autowired
    private WebSocketServer webSocket;

    @Autowired
    private MerchantOrderDao merchantOrderDao;
    /**
     * 查询所有订单
     * @param params
     * @return
     */
    @Override
        public PageUtils queryPage(Map<String, Object> params, String userId) {
        OrderEntity orderEntity = new OrderEntity().setUserId(userId);
        if(params.get("orderCode") != null && params.get("orderCode") != "") { // 根据订单编号查询
            System.err.println("orderCode" + params.get("orderCode"));
            IPage<OrderEntity> page = this.page(
                    new Query<OrderEntity>().getPage(params),
                    new LambdaQueryWrapper<OrderEntity>(orderEntity).eq(OrderEntity::getOrderCode, params.get("orderCode"))
            );
            return new PageUtils(page);
        } else if(params.get("orderStatus") != null && params.get("orderStatus") != "") { // 根据订单状态查询
            System.err.println("orderStatus" + params.get("orderStatus"));
            IPage<OrderEntity> page = this.page(
                    new Query<OrderEntity>().getPage(params),
                    new LambdaQueryWrapper<OrderEntity>(orderEntity).eq(OrderEntity::getOrderStatus, params.get("orderStatus"))
            );
            return new PageUtils(page);
        } else { // 查询全部订单
            IPage<OrderEntity> page = this.page(
                    new Query<OrderEntity>().getPage(params),
                    new QueryWrapper<OrderEntity>(orderEntity)
            );
            return new PageUtils(page);
        }
    }

    /**
     * 初始化订单
     * @param userId
     * @return
     */
    @Override
    public String create(String userId, Integer totalPrice) {
//        System.err.println(userId);
        List<CartEntity> skus1 = getSkus(userId);
        List<String> skus=new ArrayList<>();
        for (int i=0;i<skus1.size();i++){
            skus.add(skus1.get(i).getSkuId());
        }
        //把List<String> skus变成String类型并且每一个String用逗号分隔
        String skuIds = skus.stream().collect(Collectors.joining(","));
        Integer totalNumber = 0;
        Long orderCode = SnowFlakeUtil.getDefaultSnowFlakeId();

        for(String sku: skus) {
            Integer number = this.getNumber(sku, userId);
            totalNumber += number;
        }
        OrderEntity orderEntity = new OrderEntity().setUserId(userId)
                .setTotalNumber(totalNumber)
                .setTotalPrice(BigDecimal.valueOf(totalPrice))
                .setOrderCode(String.valueOf(orderCode)) // 使用雪花算法创建订单号
                .setSkuIds(skuIds)
                .setOrderStatus(0)
                .setOrderTime(new Date());
        orderDao.insert(orderEntity);
        orderDao.clearCart(userId); // 初始化订单后删除购物车
        return String.valueOf(orderCode); // 返回订单编号
    }

    @Override
    public Boolean creatOrders(HttpServletRequest request) {
        String userId=(String) request.getAttribute("userId");
        List<CartEntity> skus = getSkus(userId);
        Map<String,List<CommoditySkuEntity>> skuByMerchant=new HashMap<>();
        skus.forEach(sku->{
            CommoditySkuEntity commodityBySkuId1 = skuService.getCommodityBySkuId(sku.getSkuId());
            BigDecimal skuPrice = commodityBySkuId1.getSkuPrice();
            BigDecimal multipliedSkuPrice = skuPrice.multiply(new BigDecimal(sku.getNumber()));
            commodityBySkuId1.setSkuPrice(multipliedSkuPrice);
            commodityBySkuId1.setSkuSpecs(new BigDecimal(sku.getNumber()));
            CommoditySpuEntity commodityBySpuId = comspuService.getCommodityBySpuId(commodityBySkuId1.getSpuId());
            String merchantId=commodityBySpuId.getMerchantId();
            if(skuByMerchant.containsKey(merchantId)){
                skuByMerchant.get(merchantId).add(commodityBySkuId1 );
            }else{
                List<CommoditySkuEntity> skuList=new ArrayList<>();
                skuList.add(commodityBySkuId1);
                skuByMerchant.put(merchantId,skuList);
            }
        });
        List<OrderEntity> orderEntities=new ArrayList<>();
        skuByMerchant.forEach((merchantId,skuList)->{
            String orderCode = SnowFlakeUtil.getDefaultSnowFlakeId().toString();
            BigDecimal totalPrice=new BigDecimal(0);
            int totalNumber=0;
            for (int i=0;i<skuList.size();i++){
                totalPrice=totalPrice.add(skuList.get(i).getSkuPrice());
                totalNumber+=skuList.get(i).getSkuSpecs().intValue();
            }
            List<String> skuIds=skuList.stream().map(sku->sku.getSkuId()).collect(Collectors.toList());
            OrderEntity orderEntity = new OrderEntity().setUserId(userId)
                    .setTotalNumber(totalNumber)
                    .setTotalPrice(totalPrice)
                    .setOrderCode(orderCode) // 使用雪花算法创建订单号
                    .setSkuIds(String.join(",",skuIds))
                    .setOrderTime(new Date())
                    .setOrderStatus(0);
            System.err.println("build"+totalPrice);
            orderEntities.add(orderEntity);
                });
        this.saveBatch(orderEntities);
        orderDao.clearCart(userId);
        return true;
    }


    /**
     * 创建订单
     * @param order
     * @return
     */
    @Transactional
    @Override
    public boolean save(CreateOderDto order, String userId) {
        //把List<String> skus变成String类型并且每一个String用逗号分隔
        OrderEntity orderEntity = new OrderEntity().setUserId(userId)
                .setPaymentMode(order.getPaymentMode())
                .setTotalPrice(order.getTotalPrice())
                .setDistributionFee(order.getDistributionFee())
                .setPackingFee(order.getPackingFee())
                .setCouponId(order.getCouponId())
                .setPaymentTime(new Date())
                .setRemarks(order.getRemarks())
                .setAddressId(order.getAddressId())
                .setDeliveryTime(order.getDeliveryTime())
                .setOrderStatus(1)
                .setOrderCode(order.getOrderCode());
        orderDao.updateOrder(orderEntity);
        OrderEntity orderEntity1 = orderService.getByOrderCode(order.getOrderCode());
        String skuIds = orderEntity1.getSkuIds();
        String[] skuIds1 = skuIds.split(",");
        //获取merchant_id
        CommoditySkuEntity commodityBySkuId = skuService.getCommodityBySkuId(skuIds1[0]);
        CommoditySpuEntity commodityBySpuId = comspuService.getCommodityBySpuId(commodityBySkuId.getSpuId());
        merchantOrderService.save(new MerchantOrderEntity()
                        .setMerchant_id(commodityBySpuId.getMerchantId())
                        .setOrderId(orderEntity1.getOrderId())
                        .setDate(new Date()));
        if (webSocket.isOpen()) {
            List<MerchantOrderEntityVo> merchantOrder = merchantOrderDao.
                    getOrderMerchantListByMerId(commodityBySpuId.getMerchantId());
            JSONArray jsonArray = new JSONArray();
            merchantOrder.forEach(merchantOrderEntityVo -> {
                JsonObject jsonObject = new JsonObject();
                String orderCode = merchantOrderEntityVo.getOrderCode();
                String receiver = merchantOrderEntityVo.getReceiver();
                String receiverPhone = merchantOrderEntityVo.getReceiverPhone();
                String address = merchantOrderEntityVo.getAddress();
                String fullAddress = merchantOrderEntityVo.getFullAddress();
                String remark = merchantOrderEntityVo.getRemark();
                String sendTime = merchantOrderEntityVo.getSendTime();
                jsonObject.addProperty("orderCode", orderCode);
                jsonObject.addProperty("receiver", receiver);
                jsonObject.addProperty("receiverPhone", receiverPhone);
                jsonObject.addProperty("address", address);
                jsonObject.addProperty("fullAddress", fullAddress);
                jsonObject.addProperty("remark", remark);
                jsonObject.addProperty("sendTime",sendTime);
                jsonObject.addProperty("orderStatus", 1);
                jsonArray.put(jsonObject);
            });
            MerchantEntity byId = merchantService.getById(commodityBySpuId.getMerchantId());
            System.out.println(byId);
            try {
                String string = jsonArray.toString();
                System.out.println(string);
                webSocket.sendMessage(jsonArray.toString(), Integer.valueOf(byId.getUserId()));
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        //todo 在这添加商家关联表，由于order表内没有商家，这里用skuId去查
//        orderDao.clearCart(order.getUserId()); // 在初始化那里删除购物车
        return true; // 返回订单编号
    }


    /**
     * 创建订单之前的订单详情页面
     * @param userId
     * @return
     */
    @Override
    public DetailsVo getDetails(String userId, String orderCode, String type) {
        System.err.println(orderCode);
        List<String> skus = null;
        double totalPrice = 0;
        if(type.equals("true")) {
            String skuIds = orderDao.getSkuIdsByCode(userId,orderCode);
            String[] skusArray = skuIds.split(",");
            skus = Arrays.asList(skusArray);
            totalPrice = orderDao.getTotalPriceTruOrder(userId, orderCode);
        } else {
            List<CartEntity> skus1 = getSkus(userId);
            skus=new ArrayList<>();
           for (int i=0;i<skus1.size();i++){
               skus.add(skus1.get(i).getSkuId());
           }
            totalPrice = getTotalPrice(skus, userId);
        }
        // 获得几个sku
        DetailsVo detailsVo = new DetailsVo()
                .setTotalPrice(BigDecimal.valueOf(totalPrice))
                .setSkus(skus)
                .setDistributionFee(BigDecimal.valueOf(2))
                .setPackingFee(BigDecimal.valueOf(1));
        return detailsVo;
    }

    /**
     * 取消订单
     * @param delOrderCodes
     * @return
     */
    @Override
    public Integer cancelOrder(List<String> delOrderCodes) {
//        String userId = toDelOrders.get(0).getUserId(); // 因为是一个人的订单，所以userId都一样
//        for(int i = 0; i < toDelOrders.size(); i ++) {
//            orderCodes[i] = toDelOrders.get(i).getOrderCode();
//        }
        return orderDao.delete(new LambdaUpdateWrapper<OrderEntity>()
                .in(OrderEntity::getOrderCode, delOrderCodes));
    }

    /**
     * 新建地址
     * @param createAddressDto
     * @return
     */
    @Override
    public Integer keepAddress(CreateAddressDto createAddressDto, String userId) {
        String contactPerson = createAddressDto.getContactPerson();
        Integer phoneNumber = createAddressDto.getPhoneNumber();
        Integer call = createAddressDto.getCallName();
        Integer label = createAddressDto.getLabel();
//        String address = createAddressDto.getAddress();
        String fullAddress = createAddressDto.getFullAddress();
        String addressId = String.valueOf(SnowFlakeUtil.getDefaultSnowFlakeId());
        // 0代表不是默认地址
        return orderDao.createAddress(addressId, userId, contactPerson, phoneNumber, call, label, fullAddress, 0);
    }

    /**
     * 获得所有收获地址
     * @param userId
     * @return
     */
    @Override
    public List<AddressVo> getAllAddresses(String userId) {
        return orderDao.getAllAddresses(userId);
    }

    /**
     * 根据订单编号获得订单
     * @param orderCode
     * @return
     */
    @Override
    public OrderEntity getByOrderCode(String orderCode) {
        return orderDao.selectOne(new LambdaQueryWrapper<OrderEntity>().eq(OrderEntity::getOrderCode, orderCode));
    }

    /**
     * 获得订单详细信息
     * @param skuIds
     * @return
     */
    @Override
    public List<DishesShowVo> getDishesDetails(String skuIds, String userId) {
        String[] sku = skuIds.split(",");
        List<DishesShowVo> list = Arrays.stream(sku).map(skuId -> {
            DishesShowVo dishDetail = orderDao.getOneDishesDetails(skuId);
            dishDetail.setNumber(this.getNumber(skuId, userId));
            return dishDetail;
        }).collect(Collectors.toList());

        return list;
    }

    /**
     * 根据skuIds获得一个订单里的图片
     * @param skuIds
     * @return
     */
    @Override
    public List<String> getSrcImages(String skuIds) {
        String[] sku = skuIds.split(",");
        List<String> list = Arrays.stream(sku).map(skuId -> {
            String src = orderDao.getSrcImages(skuId);
            return src;
        }).collect(Collectors.toList());
        return list;
    }

    /**
     * 获得收获地址的详细信息
     * @param addressId
     * @return
     */
    @Override
    public AddressVo getAddressDetail(String addressId) {
        return orderDao.getAddressByAddressId(addressId);
    }

    /**
     * 获得用于首页展示的order和图片
     * @param userId
     * @return
     */
    @Override
    public IndexVo getIndexShow(String userId) {
        try {
            List<OrderEntity> orderEntities = orderDao.selectList(
                    new LambdaQueryWrapper<OrderEntity>()
                            .eq(OrderEntity::getUserId, userId)
                            .eq(OrderEntity::getOrderStatus, 1)
            );
            if(orderEntities.size() == 0) {
                return null;
            }
            OrderEntity orderEntity = orderEntities.get(0);
            List<String> skuIds = orderDao.getSkuIds(userId, 1);
            List<String> srcImages = this.getSrcImages(skuIds.get(0));
            IndexVo indexShow = new IndexVo().setOrder(orderEntity).setSrcImages(srcImages);
            return indexShow;
        } catch (Exception e) {
            e.printStackTrace();
        }
        //通过userId获得待收货的skuIds
        return null;
    }

    @Override
    public Boolean receivin(String orderCode) {
        UpdateWrapper<OrderEntity> wrapper=new UpdateWrapper<OrderEntity>()
                .eq("order_code",orderCode)
                .set("order_status",3);
        return this.update(wrapper);
    }

    /**
     * 根据sku的id获得价格总和
     * @param skus
     * @return
     */
    public double getTotalPrice(List<String> skus, String userId) {
        return orderDao.getTotalPrice(skus, userId);
    }

    /**
     * 获得用户购物车的skuid
     * @param userId
     * @return
     */
    public List<CartEntity> getSkus(String userId) {
        QueryWrapper<CartEntity> wrapper=new QueryWrapper<CartEntity>()
                .eq("user_id",userId);
        return cartService.list(wrapper);
    }

    /**
     * 获得一个订单中某个商品的数量
     * @param skuId
     * @return
     */
    public Integer getNumber(String skuId, String userId) {
        return orderDao.getNumber(skuId, userId);
    }

    public String getUserId(String openId) {
        return orderDao.getUserId(openId);
    }





}